
from rest_framework import serializers
from asset.models import *
from oauth.models import *
from .mixins  import *
import json
import re
from django.conf import settings


from django.contrib.auth import get_user_model
Users = get_user_model()

from utils.Ldap import Ladp_Tools
from utils.custom_log   import log_start
logger = log_start('Userserializers')

#### 个人中心 ####
class ChangePasswordSerializer(serializers.ModelSerializer):
    """
    个人中心修改密码序列化器
    """
    old_password = serializers.CharField(write_only=True, required=True)
    confirm_password = serializers.CharField(write_only=True, required=True)

    class Meta:
        model = Users
        fields = ['old_password', 'password', 'confirm_password']
        extra_kwargs = {
            'password': {
                'required': True,
                'max_length': 20,
                'min_length': 6,
                'write_only': True,
                'error_messages': {
                    'max_length': '密码长度应在6 到 20位',
                    'min_length': '密码长度应在6 到 20位',
                }
            }
        }

    def validate(self, attrs):
        """ 判断本地密码验证是否成功,失败尝试LDAP"""
        if not self.instance.check_password(attrs.get('old_password')):

            tools = Ladp_Tools()
            uid = self.instance.username
            old_passwd = attrs.get('old_password')
            new_passwd = attrs.get('password')
            ret = tools.ldap_get_vaild(uid,old_passwd)

            if ret: 
                """同步密码到LDAP"""
                tools.ldap_update_pass(uid,old_passwd,new_passwd)
            else:
                raise serializers.ValidationError('原密码错误')

        if attrs.get('confirm_password') != attrs.get('password'):
            raise serializers.ValidationError('两次输入密码不一致')
        return attrs

    def update(self, instance, validated_data):
        self.instance.set_password(validated_data.get('password'))
        self.instance.save()
        return self.instance


class ChangeInformationSerializer(serializers.ModelSerializer):
    """
    个人中心修改个人信息序列化器
    """
    mobile = serializers.RegexField(r'^1[3-9]\d{9}$', allow_blank=True, error_messages={'invalid': '手机号格式错误'})

    class Meta:
        model = Users
        fields = ['name', 'mobile', 'email']

    @staticmethod
    def validate_mobile(mobile):
        # 避免字段为 '' 时 models unique约束失败
        if mobile == '':
            return None
        else:
            return mobile


class ChangeAvatarSerializer(serializers.ModelSerializer):
    """
    个人中心修改个人头像序列化器
    """

    class Meta:
        model = Users
        fields = ['image']


class UserProfileserializer(serializers.ModelSerializer):
    """
    用户增删改查序列化器
    """

    roles_list = serializers.SerializerMethodField()
    date_joined = serializers.DateTimeField(format='%Y-%m-%d %H:%M:%S', read_only=True)
    department_name = serializers.ReadOnlyField(source='department.name')
    is_superuser = serializers.BooleanField(read_only=True)

    class Meta:
        model = UserProfile
        fields = ['id','username','name','mobile','email','is_active','department',
        'department_name','date_joined','roles','roles_list','is_superuser','position']
        # depth = 1
    
    def validate(self, attrs):
        # 数据验证
        if attrs.get('username'):
            if attrs.get('username').isdigit():
                raise serializers.ValidationError('用户名不能为纯数字')
        if attrs.get('mobile'):
            if not re.match(r'^1[3-9]\d{9}$', attrs.get('mobile')):
                raise serializers.ValidationError('手机格式不正确')
        if attrs.get('mobile') == '':
            attrs['mobile'] = None

        return attrs

    def get_roles(self, obj):
        return [role.id for role in obj.roles.all()]

    def get_roles_list(self, obj):
        return [{'id': role.id, 'desc': role.desc} for role in obj.roles.all()]

    def create(self, validated_data):
        user = super().create(validated_data)
        # 添加默认密码
        user.set_password(settings.DEFAULT_PWD)
        user.save()
        return user

class AssetsAdminSerializer(serializers.ModelSerializer):
    """
    资产管理员序列化器
    """

    class Meta:
        model = Users
        fields = ['id', 'username']

class UsersPartialSerializer(serializers.ModelSerializer):
    """
    用户局部更新(激活/锁定)序列化器
    """
    class Meta:
        model = Users
        fields = ['id', 'is_active']




class ResetPasswordSerializer(serializers.ModelSerializer):
    """
    重置密码序列化器
    """
    confirm_password = serializers.CharField(write_only=True)

    class Meta:
        model = Users
        fields = ['id', 'password', 'confirm_password']
        extra_kwargs = {
            'password': {
                'write_only': True
            }
        }

    def validate(self, attrs):
        # partial_update, 局部更新required验证无效, 手动验证数据
        password = attrs.get('password')
        confirm_password = attrs.get('confirm_password')
        if not password:
            raise serializers.ValidationError('字段password为必填项')
        if not confirm_password:
            raise serializers.ValidationError('字段confirm_password为必填项')
        if password != confirm_password:
            raise serializers.ValidationError('两次密码不一致')
        return attrs

    def save(self, **kwargs):
        # 重写save方法, 保存密码
        self.instance.set_password(self.validated_data.get('password'))
        self.instance.save()
        return self.instance


